﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Diagnostics;
using ComLib.ComType;

namespace CoreBroker
{
    public class PassElements
    {
        /// <summary>
        /// 脸部和眼睛识别通过
        /// </summary>
        private bool _bFaceEyeDetected = false;
        public bool FaceEye
        {
            get { return _bFaceEyeDetected; }
            set { _bFaceEyeDetected = value; }
        }

        /// <summary>
        /// 正面识别通过
        /// </summary>
        private bool _bFrontDetected = false;
        public bool Front
        {
            get { return _bFrontDetected; }
            set { _bFrontDetected = value; }
        }

        /// <summary>
        /// 一所质检通过
        /// </summary>
        private bool _bQcDllCheck = false;
        public bool QcDllCheck
        {
            get { return _bQcDllCheck; }
            set { _bQcDllCheck = value; }
        }

        /// <summary>
        /// 像素检测通过
        /// </summary>
        private bool _bPxlQcPass = false;
        public bool PxlQcPass
        {
            get { return _bPxlQcPass; }
            set { _bPxlQcPass = value; }
        }

        /// <summary>
        /// 照片检测是否通过
        /// </summary>
        private bool _bDetectPassed = false;
        public bool DetectPassed
        {
            get { return _bDetectPassed; }
            set { _bDetectPassed = value; }
        }

        public void Reset()
        {
            _bPxlQcPass = false;
            _bQcDllCheck = false;
            _bFrontDetected = false;
            _bFaceEyeDetected = false;
            _bDetectPassed = false;
        }
    }

    /// <summary>
    /// 标识应该显示的方向提示图
    /// </summary>
    public struct DetectFaceEyePosition
    {
        /// <summary>
        /// 人脸位置
        /// </summary>
        public Rectangle RecFace;

        /// <summary>
        /// 左眼睛位置
        /// </summary>
        public Rectangle RecEyeLeft;

        /// <summary>
        /// 右眼睛位置
        /// </summary>
        public Rectangle RecEyeRight;

        /// <summary>
        /// 检测结果
        /// </summary>
        public TipImageType FixeDirectionAdvice;
    }

    /// <summary>
    /// 面部特征的检测结果
    /// </summary>
    public class FeaturePosition
    {
        /// <summary>
        /// 人脸位置
        /// </summary>
        private Rectangle _recFace = new Rectangle();
        public Rectangle FaceRec
        {
            get { return _recFace; }
            set { _recFace = value; }
        }

        /// <summary>
        /// 眼睛位置
        /// </summary>
        private List<Rectangle> _recEye = new List<Rectangle>();
        public List<Rectangle> Eyes
        {
            get { return _recEye; }
            set { _recEye = value; }
        }

        /// <summary>
        /// 肩膀位置
        /// </summary>
        private List<Point> _posShoulder = new List<Point>();
        public List<Point> Shoulder
        {
            get { return _posShoulder; }
            set { _posShoulder = value; }
        }

        private TipImageType _fixeDirectionAdvice = TipImageType.Normal;
        public TipImageType FixeDirectionAdvice
        {
            get
            {
                return _fixeDirectionAdvice;
            }
            set
            {
                _fixeDirectionAdvice = value;
            }
        }

        /// <summary>
        /// 头顶位置
        /// </summary>
        private Point _posHeadTop = new Point();
        public Point HeadTop
        {
            get { return _posHeadTop; }
            set { _posHeadTop = value; }
        }

        private FGFacePoint _facePoint = new FGFacePoint();
        public FGFacePoint FacePoint
        {
            get
            {
                return _facePoint;
            }
            set
            {
                _facePoint = value;
            }
        }

        public void Reset()
        {
            _fixeDirectionAdvice = TipImageType.Normal;
            _facePoint = new FGFacePoint();
            _posHeadTop = Point.Empty;
            _posShoulder.Clear();
            _recEye.Clear();
            _recFace.X = 0;
            _recFace.Y = 0;
            _recFace.Width = 0;
            _recFace.Height = 0;
        }

        public void AdjustEyes()
        {
            if (_recEye.Count == 2)
            {
                //判断左右眼（右眼的x大，左眼的x小），设Index=0为左眼，index=1为右眼
                if (_recEye[0].X > _recEye[1].X)
                {
                    Rectangle rectTmp = new Rectangle();
                    rectTmp = _recEye[0]; //调换
                    _recEye[0] = _recEye[1];
                    _recEye[1] = rectTmp;
                }
            }
        }

        public Point GetLeftEyeCenter()
        {
            Point p = new Point();
            if (!IsEyesEmpty())
            {
                p.X = _recEye[0].X + _recEye[0].Width / 2;
                p.Y = _recEye[0].Y + _recEye[0].Height / 2;
            }
            return p;
        }

        public Point GetRightEyeCenter()
        {
            Point p = new Point();
            if (!IsEyesEmpty())
            {
                p.X = _recEye[1].X + _recEye[1].Width / 2;
                p.Y = _recEye[1].Y + _recEye[1].Height / 2;
            }
            return p;
        }

        public bool IsEyesEmpty()
        {
            if (Eyes.Count == 2)
            {
                if (Eyes[0].X > 0
                    && Eyes[0].Y > 0
                    && Eyes[1].X > 0
                    && Eyes[1].Y > 0)
                {
                    return false;
                }
            }
            return true;
        }

        public DetectFaceEyePosition GetFaceEyePosition()
        {
            DetectFaceEyePosition position = new DetectFaceEyePosition();
            position.RecFace = _recFace;
            if (_recEye != null && _recEye.Count == 2)
            {
                // 判断左右眼（右眼的x大，左眼的x小）                     
                // 示意朝右的放在脸颊左侧
                // 先找到左眼位置
                position.RecEyeLeft = (_recEye[0].X < _recEye[1].X) ? _recEye[0] : _recEye[1];
                position.RecEyeRight = (_recEye[0].X < _recEye[1].X) ? _recEye[1] : _recEye[0];
                position.FixeDirectionAdvice = FixeDirectionAdvice;
            }
            else
            {
                position.FixeDirectionAdvice = TipImageType.None;
            }
            return position;
        }
    }

    public class CustomStdDetectOption
    {
        /// <summary>
        /// 脸部曝光检测结果
        /// </summary>
        private DeviationState _faceExpState = DeviationState.Normal;
        public DeviationState FaceExpState
        {
            get { return _faceExpState; }
            set { _faceExpState = value; }
        }

        /// <summary>
        /// 脸部曝光检测结果
        /// </summary>
        private DeviationState _faceBrightState = DeviationState.Normal;
        public DeviationState FaceBrightState
        {
            get { return _faceBrightState; }
            set { _faceBrightState = value; }
        }

        private FaceColor _faceColor = new FaceColor();
        public FaceColor LAB
        {
            get
            {
                return _faceColor;
            }
            set
            {
                _faceColor = value;
            }
        }

        public void SetLAB(float l, float a, float b)
        {
            _faceColor.L = l;
            _faceColor.A = a;
            _faceColor.B = b;
        }

        public void Reset()
        {
            _faceExpState = DeviationState.Normal;
            _faceExpState = DeviationState.Normal;
            _faceColor.Reset();
        }
    }


    /// <summary>
    /// 矫正参考信息及建议。。。
    /// </summary>
    public class Corrections
    {
        private int _faceroll = -2;						// 脸旋转-1：脸逆时针转，1：脸顺时针转，0:没转，-2未知
        public int Faceroll
        {
            get
            {
                return _faceroll;
            }
            set
            {
                _faceroll = value;
            }
        }
        private int _faceyaw = -2;						        // 脸侧转-1：脸向左侧转，1：脸向右侧转，0:没转，-2未知
        public int Faceyaw
        {
            get
            {
                return _faceyaw;
            }
            set
            {
                _faceyaw = value;
            }
        }

        private int _headpitch = -2;					        // 头俯昂-1：头向下俯, 1：头向上昂，0:不俯昂，-2未知
        public int Headpitch
        {
            get
            {
                return _headpitch;
            }
            set
            {
                _headpitch = value;
            }
        }

        /// <summary>
        /// -1左肩高，1右肩高，0正常
        /// </summary>
        private int _shoulderLine = 0;
        public int ShoulderLine
        {
            get
            {
                return _shoulderLine;
            }
            set
            {
                _shoulderLine = value;
            }
        }

        // 亮度偏移
        private int _brightnessOffset = -2; // 曝光指示：-1曝光不足，1曝光过度，0正常，-2未知
        public int BrightnessOffset
        {
            get { return _brightnessOffset; }
            set { _brightnessOffset = value; }
        }

        //头长偏移（应对一所头长过大）
        private int _headHeightOffSet = 0;
        public int HeadHeightOffSet
        {
            get { return _headHeightOffSet; }
            set { _headHeightOffSet = value; }
        }

        private string _tips = "";
        public string Tips
        {
            get { return _tips; }
            set { _tips = value; }
        }

        public void RemainFirstError()
        {
            if (_tips.Contains(";"))
            {
                string[] sArray = _tips.Split(';');
                if (sArray.Count() > 0)
                {
                    _tips = sArray.First();
                }
                return;
            }
            if (_tips.Contains("；"))
            {
                string[] sArray = _tips.Split('；');
                if (sArray.Count() > 0)
                {
                    _tips = sArray.First();
                }
                return;
            }
        }

        public void Reset()
        {
            _tips = "";
            _headHeightOffSet = 0;
            _brightnessOffset = -2;
            _shoulderLine = 0;
            _headpitch = -2;
            _faceyaw = -2;
            _faceroll = -2;
        }
    }

    public class ProcessRecord
    {
        //开始拍照（一所第一次质检成功后）
        private bool _bBeginShoot = false;
        public bool BeginShoot
        {
            get { return _bBeginShoot; }
            set { _bBeginShoot = value; }
        }

        /// <summary>
        /// 镜头是否移动
        /// </summary>
        private bool _bCamMoving = false;
        public bool CamMoving
        {
            get { return _bCamMoving; }
            set { _bCamMoving = value; }
        }

        /// <summary>
        /// 电机本次移动步数
        /// </summary>
        private int _nMoveSteps = 0;
        public int MoveSteps
        {
            get { return _nMoveSteps; }
            set { _nMoveSteps = value; }
        }

        /// <summary>
        /// 原图LAB
        /// </summary>
        private FaceColor _srcFaceColor = new FaceColor();
        public FaceColor SrcLAB
        {
            get
            {
                return _srcFaceColor;
            }
            set
            {
                _srcFaceColor = value;
            }
        }

        /// <summary>
        /// 重置参数
        /// </summary>
        public void Reset()
        {
            _bCamMoving = false;
            _nMoveSteps = 0;
        }

        /// <summary>
        /// 重置所有参数
        /// </summary>
        public void ResetAll()
        {
            _bBeginShoot = false;
            _bCamMoving = false;
            _nMoveSteps = 0;
            _srcFaceColor.Reset();
        }
    }

    /// <summary>
    /// 人脸识别算法的输出参数
    /// </summary>
    public class RecogOut : ICloneable
    {
        /// <summary>
        /// 照片检测永远无法通过
        /// </summary>
        private bool _bNeverPass = false;
        public bool NeverPass
        {
            get { return _bNeverPass; }
            set { _bNeverPass = value; }
        }

        /// <summary>
        /// 照片检测永远无法通过的原因
        /// </summary>
        private string _neverPassReason = "";
        public string NeverPassReason
        {
            get { return _neverPassReason; }
            set { _neverPassReason = value; }
        }

        /// <summary>
        /// 检测计算结果
        /// </summary>
        private FeaturePosition _computation;
        public FeaturePosition Computation
        {
            get
            {
                return _computation;
            }
            set
            {
                _computation = value;
            }
        }

        /// <summary>
        /// 自定义检测选项
        /// </summary>
        private CustomStdDetectOption _customStdDetectOpt;
        public CustomStdDetectOption CustomDetectOpt
        {
            get
            {
                return _customStdDetectOpt;
            }
            set
            {
                _customStdDetectOpt = value;
            }
        }

        /// <summary>
        /// 矫正参考信息
        /// </summary>
        private Corrections _correction;
        public Corrections Correction
        {
            get
            {
                return _correction;
            }
            set
            {
                _correction = value;
            }
        }

        /// <summary>
        /// 所有检测项通过信息
        /// </summary>
        private PassElements _passElems;
        public PassElements PassElems
        {
            get
            {
                return _passElems;
            }
            set
            {
                _passElems = value;
            }
        }

        /// <summary>
        /// 处理过程记录
        /// </summary>
        private ProcessRecord _processing;
        public ProcessRecord Processing
        {
            get
            {
                return _processing;
            }
            set
            {
                _processing = value;
            }
        }

        private UnAcceptableItem _unAcceptItem = UnAcceptableItem.None;
        public UnAcceptableItem UnAcceptItem
        {
            get
            {
                return _unAcceptItem;
            }
            set
            {
                _unAcceptItem = value;
            }
        }

        /// <summary>
        /// 待处理原图的保存路径
        /// </summary>
        private string _srcImagePath = null;
        public string SourceImagePath
        {
            get
            {
                return _srcImagePath;
            }
            set
            {
                _srcImagePath = value;
            }
        }

        /// <summary>
        /// 经过一系列处理后图像的保存路径
        /// </summary>
        private string _destImagePath = null;
        public string DestImagePath
        {
            get
            {
                return _destImagePath;
            }
            set
            {
                _destImagePath = value;
            }
        }

        /// <summary>
        /// 检测持续时间
        /// </summary>
        public long ElapsedMilliseconds
        {
            get;
            set;
        }

        public RecogOut()
        {
            _processing = new ProcessRecord();
            _passElems = new PassElements();
            _customStdDetectOpt = new CustomStdDetectOption();
            _correction = new Corrections();
            _computation = new FeaturePosition();
        }

        /// <summary>
        /// 重置参数
        /// </summary>
        public void Reset()
        {
            _processing.Reset();
            _customStdDetectOpt.Reset();
            _correction.Reset();
            _passElems.Reset();
            _computation.Reset();
            _unAcceptItem = UnAcceptableItem.None;
            _srcImagePath = "";
            _destImagePath = "";
        }

        /// <summary>
        /// 重置所有参数
        /// </summary>
        public void ResetAll()
        {
            _processing.ResetAll();
            _customStdDetectOpt.Reset();
            _correction.Reset();
            _passElems.Reset();
            _computation.Reset();
            _unAcceptItem = UnAcceptableItem.None;
            _srcImagePath = "";
            _destImagePath = "";
            _bNeverPass = false;
            _neverPassReason = "";
        }

        public object Clone()
        {
            RecogOut clone = new RecogOut();
            return clone;
        }
    }

    /// <summary>
    /// 标识应该显示的方向提示图
    /// </summary>
    public enum TipImageType : uint
    {
        Normal = 0,
        FaceLeft,
        FaceRight,
        HeadLeft,
        HeadRight,
        HeadUp,
        HeadDown,
        ShoulderLeft,
        ShoulderRight,
        None
    }

    /// <summary>
    /// 参数相对正常范围的偏移状态
    /// </summary>
    public enum DeviationState : uint
    {
        Normal = 0,                   // 正常
        Below = 1,                     // 低于正常范围
        Above = 2,                    // 超过正常范围  
        Exception = 3,               // 检测异常
        Unkown = 4                  // 检测异常
    }

    /// <summary>
    /// 不合格项类型
    /// </summary>
    public enum UnAcceptableItem : uint
    {
        Head = 0,
        Face = 1,
        Eye = 2,
        Background = 3,
        Front = 4,
        PXL = 5, // 像素算法
        QC = 6, // 一所检测
        PxlAssessApplyProfile = 7, // 应用评价策略
        Crop = 8,
        Denosing = 9,
        FormatInvert = 10,
        AdjustColor = 11,
        GetDetectAccess = 12,
        CleanBackColor = 13,
        Shoulder = 14,
        RunningException = 15,
        PxlDetectAssess = 16, // 照片质量评价
        Other = 17,
        None = 18
    }

    public class FaceColor
    {
        /// <summary>
        /// 脸部L值
        /// </summary>
        private float _fl = 0.0f;
        public float L
        {
            get { return _fl; }
            set { _fl = value; }
        }

        /// <summary>
        /// 脸部A值
        /// </summary>
        private float _fa = 0.0f;
        public float A
        {
            get { return _fa; }
            set { _fa = value; }
        }

        /// <summary>
        /// 脸部B值
        /// </summary>
        private float _fb = 0.0f;
        public float B
        {
            get { return _fb; }
            set { _fb = value; }
        }

        public FaceColor()
        {

        }

        public FaceColor(float l, float a, float b)
        {
            L = l;
            A = a;
            B = b;
        }

        public void Reset()
        {
            L = 0.0f;
            A = 0.0f;
            B = 0.0f;
        }

        public void SetValue(float l, float a, float b)
        {
            L = l;
            A = a;
            B = b;
        }

        public bool IsEmpty()
        {
            return (L.Equals(0.0f)
                || L.Equals(0.0f)
                || L.Equals(0.0f));
        }

        public override string ToString()
        {
            return string.Format("L:{0}, A:{1}, B:{2}", L, A, B);
        }
    }
}
